package com.kinghood.productcenter.service.product.handler;

import com.alibaba.excel.util.ListUtils;
import com.alibaba.fastjson.JSON;
import com.kinghood.infrastructure.model.KingHoodException;
import com.kinghood.infrastructure.model.KingHoodExceptionUtil;
import com.kinghood.infrastructure.util.base.IdGenUtil;
import com.kinghood.productcenter.common.model.dao.base.BaseAttributeDO;
import com.kinghood.productcenter.common.model.dao.base.BaseAttributeLimitDO;
import com.kinghood.productcenter.common.model.dao.base.BaseAttributeValueDO;
import com.kinghood.productcenter.common.model.dao.product.*;
import com.kinghood.productcenter.common.model.dto.product.*;
import com.kinghood.productcenter.common.model.dto.sku.ProductSkuDTO;
import com.kinghood.productcenter.common.model.dto.sku.ProductSkuReqDTO;
import com.kinghood.productcenter.common.model.dto.sku.SkuDTO;
import com.kinghood.productcenter.common.model.enums.base.AttributeValueCodeEnum;
import com.kinghood.productcenter.common.model.enums.product.ProductSkuStatusEnums;
import com.kinghood.productcenter.common.model.enums.product.ProductStatusEnums;
import com.kinghood.productcenter.common.model.vo.product.ProductDetailVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * description
 *
 * @author zhangFanJun
 * @date 2023-12-26 11:42
 **/
@Slf4j
public class ProductBaseHandler {

    private final static int LIMIT_SIZE = 10 * 1024 * 1024;
    private final static int UNIT_SIZE = 1024;
    public static final Pattern TIME_PATTERN = Pattern.compile("^\\d{4}+\\-+\\d{1,2}+\\-+\\d{1,2} \\d{2}+\\:+\\d{1,2}+\\:+\\d{1,2}$");
    public static final Pattern TIME_PATTERN01 = Pattern.compile("^\\d{4}+\\-+\\d{1,2}+\\-+\\d{1,2}");
    public static final Pattern TIME_PATTERN2 = Pattern.compile("^\\d{4}+\\/+\\d{1,2}+\\/+\\d{1,2} \\d{2}+\\:+\\d{1,2}+\\:+\\d{1,2}$");
    public static final Pattern TIME_PATTERN21 = Pattern.compile("^\\d{4}+\\/+\\d{1,2}+\\/+\\d{1,2}");


    public static String handleValueParam(String value) {

        if(StringUtils.isEmpty(value)){
            return value;
        }
        // 去掉*
        if (value.startsWith("*")) {
            value = value.substring(1);
        }
        return value;
    }

    /**
     * 处理excel数据
     * */
    public static List<ProductExcelRowDTO> handleExcelData(List<Map<Integer, String>> cachedDataList, Map<Integer, ProductExcelAttributeDTO> headCodeMap, BaseProductDaoDTO dao, RowFieldRecordDTO rowFieldRecord){

        List<ProductExcelRowDTO> rowList = new ArrayList<>();
        for (int i = 0; i < cachedDataList.size(); i++) {
            Map<Integer, String> data = cachedDataList.get(i);
            AtomicBoolean bad = new AtomicBoolean(false);
            AtomicReference<String> message = new AtomicReference();
            Map<Integer, ExcelDataInfoDTO> map = new HashMap<>();
            ProductExcelRowDTO row = new ProductExcelRowDTO();
            row.setIndex(i);
            row.setMap(map);
            rowList.add(row);

            // 行数据解析
            data.forEach((key, value) -> {
                ProductExcelAttributeDTO code = headCodeMap.get(key);
                if(Objects.isNull(code)){
                    log.info("{}列因为没有标题不解析",key+1);
                    return;
                }
                ExcelDataInfoDTO one = new ExcelDataInfoDTO();
                one.setIndex(key);
                one.setValue(value);
                map.put(key, one);
                if (bad.get()) {
                    return;
                }

                // 属性
                if (Objects.equals(code.getIsAttribute(), Boolean.TRUE)) {
                    if (StringUtils.isEmpty(value)) {
                        return;
                    }
                    one.setAttributeId(code.getAttributeId());
                    one.setAttributeCode(code.getAttributeCode());
                    one.setAttributeName(code.getAttributeName());
                    one.setValueCode(code.getValueCode());
                    one.setValueType(code.getValueType());
                    one.setIsMultipleChoice(code.getIsMultipleChoice());
                    one.setAttributeLimit(code.getAttributeLimit());
                    one.setAttributeValueMap(code.getAttributeValueMap());
                }
                if (Objects.isNull(code.getCode())) {
                    return;
                }
                // 系统字段
                switch (code.getCode()) {
                    case "styleNumber":
                        one.setStyleNumber(value);
                        row.setStyleNumber(value);
                        if (StringUtils.isEmpty(value)) {
                            bad.set(true);
                            message.set("款号未填");
                        } else
                        if (dao.getStyleList().contains(value)) {
                            bad.set(true);
                            message.set("款号已经存在");
                        }
                        break;
                    case "styleName":
                        one.setStyleName(value);
                        row.setStyleName(value);
                        if (StringUtils.isEmpty(value)) {
                            bad.set(true);
                            message.set("款式名未填");
                        }
                        break;
                    case "brand":
                        Long brandId = dao.getBrandMap().get(value);
                        one.setBrandId(brandId);
                        row.setBrandId(brandId);
                        if (Objects.isNull(brandId)) {
                            bad.set(true);
                            message.set("品牌检查不通过");
                        }
                        break;
                    case "goods":
                        Long goodsId = dao.getGoodsMap().get(value);
                        one.setGoodsId(goodsId);
                        row.setGoodsId(goodsId);
                        if (Objects.isNull(goodsId)) {
                            bad.set(true);
                            message.set("货类检查不通过");
                        }
                        break;
                    case "category":
                        Long categoryId = dao.getCategoryMap().get(value);
                        one.setCategoryId(categoryId);
                        row.setCategoryId(categoryId);
                        if (Objects.isNull(categoryId)) {
                            bad.set(true);
                            message.set("品类检查不通过");
                        }
                        break;
                    case "status":
                        Integer status = ProductStatusEnums.getTypeByName(value);
                        one.setStatus(status);
                        row.setStatus(status);
                        if (Objects.isNull(status)) {
                            bad.set(true);
                            message.set("状态异常");
                        }
                        break;
                    case "skuCode":
                        if (StringUtils.isEmpty(value)) {
                            break;
                        }
                        one.setSkuCode(value);
                        row.setSkuCode(value);
                        if (dao.getSkuCodeList().contains(value)) {
                            bad.set(true);
                            message.set("SKU编码已经存在");
                        }
                        break;
                    case "skuStatus":
                        if (StringUtils.isEmpty(value)) {
                            break;
                        }
                        Integer skuStatus = ProductSkuStatusEnums.getTypeByName(value);
                        one.setSkuStatus(skuStatus);
                        row.setSkuStatus(skuStatus);
                        if (Objects.isNull(skuStatus)) {
                            bad.set(true);
                            message.set("SKU状态填停用或者启用");
                        }
                        break;
                    case "supplier":
                        if (StringUtils.isEmpty(value)) {
                            break;
                        }
                        Long supplierId = dao.getSupplierMap().get(value);
                        one.setSupplierId(supplierId);
                        row.setSupplierId(supplierId);
                        if (Objects.isNull(supplierId)) {
                            bad.set(true);
                            message.set("供应商检查不通过");
                        }
                        break;
                    default:
                }
            });
            if(StringUtils.isEmpty(row.getStyleNumber())){
                bad.set(true);
                message.set("款号必填");
            }
            // 填了sku编码后，sku状态必填
            if(!StringUtils.isEmpty(row.getSkuCode()) && StringUtils.isEmpty(row.getSkuStatus())){
                bad.set(true);
                message.set("sku状态未填");
            }

            if (bad.get()) {
                int size = rowFieldRecord.getSize();
                row.setBad(true);
                row.setBadMessage(message.get());
                ExcelDataInfoDTO one = new ExcelDataInfoDTO();
                one.setIndex(size);
                one.setValue("导入失败");
                one.setBad(true);
                map.put(size, one);
                ExcelDataInfoDTO two = new ExcelDataInfoDTO();
                two.setIndex(size + 1);
                two.setValue(message.get());
                two.setBad(true);
                map.put(size + 1, two);
            }
        }

        return rowList;
    }


    /**
     * 已经分组好后的excel数据
     */
    public static ProductExcelDaoDTO handleProductData(List<ProductExcelRowDTO> list, RowFieldRecordDTO rowFieldRecord, BaseProductDaoDTO dao) {

        ProductExcelDaoDTO res = new ProductExcelDaoDTO();

        // 检查数据是否出现不一致的情况
        boolean bad = checkSameData(list, rowFieldRecord, dao);
        // 收集sku编码
        List<String> addList = list.stream().map(x -> {
            ExcelDataInfoDTO index = x.getMap().get(rowFieldRecord.getSkuStart());
            if (Objects.nonNull(index)) {
                return index.getValue();
            }
            return null;
        }).filter(Objects::nonNull).collect(Collectors.toList());
        dao.getSkuCodeList().addAll(addList);


        // 当有一个坏数据，整个失效
        if (bad) {
            String message = list.stream()
                    .filter(ProductExcelRowDTO::isBad)
                    .map(ProductExcelRowDTO::getBadMessage)
                    .findFirst().orElse(null);
            list.forEach(x -> {
                if (!x.isBad()) {
                    badData(x, message,rowFieldRecord.getSize());
                }
            });
            return null;
        } else {
            list.forEach(x -> {
                if (!x.isBad()) {
                    x.setSuccess(true);
                    int size = rowFieldRecord.getSize();
                    ExcelDataInfoDTO one = new ExcelDataInfoDTO();
                    one.setIndex(size);
                    one.setValue("导入成功");
                    x.getMap().put(size, one);
                }
            });
        }

        LocalDateTime now = LocalDateTime.now();
        ProductBaseDO productBaseDO = res.getProductBaseDO();
        List<ProductAttributeDO> attributes = res.getAttributes();
        List<ProductSkuBaseDO> skuBaseList = res.getSkuBaseList();
        List<ProductSkuSupplierBaseDO> supplierBaseList = res.getSupplierBaseList();
        List<ProductSkuExtrasBaseDO> extrasBaseList = res.getExtrasBaseList();

        // 商品
        ProductExcelRowDTO first = list.get(0);
        productBaseDO.setId(IdGenUtil.getId());
        productBaseDO.setStyleNumber(first.getStyleNumber());
        productBaseDO.setStyleName(first.getStyleName());
        productBaseDO.setStatus(first.getStatus());
        productBaseDO.setBrandId(first.getBrandId());
        productBaseDO.setGoodsId(first.getGoodsId());
        productBaseDO.setCategoryId(first.getCategoryId());

        productBaseDO.setCreateTime(now);
        productBaseDO.setUpdateTime(now);
        productBaseDO.setCreateUserId(rowFieldRecord.getUserId());
        productBaseDO.setUpdateUserId(rowFieldRecord.getUserId());
        Map<Integer, ExcelDataInfoDTO> dataMap = first.getMap();

        // 商品属性，first是第一行数据
        for (int i = rowFieldRecord.getProductStart(); i <= rowFieldRecord.getProductEnd(); i++) {
            ExcelDataInfoDTO info = dataMap.get(i);
            if (Objects.isNull(info) || Objects.isNull(info.getAttributeId()) || StringUtils.isEmpty(info.getValue())) {
                continue;
            }
            ProductAttributeDO attribute = new ProductAttributeDO();
            attributes.add(attribute);
            attribute.setId(IdGenUtil.getId());
            attribute.setProductId(productBaseDO.getId());
            attribute.setBusinessId(productBaseDO.getId());
            attribute.setBusinessType(ProductAttributeDO.BUSINESS_TYPE_PRODUCT);
            attribute.setAttributeId(info.getAttributeId());
            attribute.setAttributeCode(info.getAttributeCode());
            attribute.setValueType(info.getValueType());
            attribute.setValue(ProductBaseHandler.handleAttributeValue(info));
//            attribute.setValueFind(ProductBaseHandler.handleAttributeValueFind(info));
            attribute.setValueFind(attribute.getValue());
            attribute.setCreateTime(now);
            attribute.setUpdateTime(now);
            attribute.setCreateUserId(rowFieldRecord.getUserId());
            attribute.setUpdateUserId(rowFieldRecord.getUserId());
        }

        Map<String, ProductExcelRowDTO> skuMap = list.stream()
                .filter(x->Objects.nonNull(x.getSkuCode()))
                .collect(Collectors.toMap(k -> k.getStyleNumber() + k.getSkuCode(), v -> v, (k1, k2) -> k2));
        // sku
        for (ProductExcelRowDTO value : skuMap.values()) {
            if (StringUtils.isEmpty(value.getSkuCode())) {
                continue;
            }
            ProductSkuBaseDO skuBase = new ProductSkuBaseDO();
            skuBaseList.add(skuBase);
            skuBase.setId(IdGenUtil.getId());
            skuBase.setProductId(productBaseDO.getId());
            skuBase.setSkuUuid(skuBase.getId().toString());
            skuBase.setSkuCode(value.getSkuCode());
            skuBase.setSkuStatus(value.getSkuStatus());
            skuBase.setCreateTime(now);
            skuBase.setUpdateTime(now);
            skuBase.setCreateUserId(rowFieldRecord.getUserId());
            skuBase.setUpdateUserId(rowFieldRecord.getUserId());
            // sku属性
            for (int i = rowFieldRecord.getSkuStart(); i <= rowFieldRecord.getSkuEnd(); i++) {
                ExcelDataInfoDTO info = value.getMap().get(i);
                if (Objects.isNull(info) || Objects.isNull(info.getAttributeId()) || StringUtils.isEmpty(info.getValue())) {
                    continue;
                }
                ProductAttributeDO attribute = new ProductAttributeDO();
                attributes.add(attribute);
                attribute.setId(IdGenUtil.getId());
                attribute.setProductId(productBaseDO.getId());
                attribute.setBusinessId(skuBase.getId());
                attribute.setBusinessType(ProductAttributeDO.BUSINESS_TYPE_SKU);
                attribute.setAttributeId(info.getAttributeId());
                attribute.setAttributeCode(info.getAttributeCode());
                attribute.setValueType(info.getValueType());
                attribute.setValue(ProductBaseHandler.handleAttributeValue(info));
//                attribute.setValueFind(ProductBaseHandler.handleAttributeValueFind(info));
                attribute.setValueFind(attribute.getValue());
                attribute.setCreateTime(now);
                attribute.setUpdateTime(now);
                attribute.setCreateUserId(rowFieldRecord.getUserId());
                attribute.setUpdateUserId(rowFieldRecord.getUserId());
            }
        }

        Map<String, Long> skuIdMap = skuBaseList.stream().collect(Collectors.toMap(ProductSkuBaseDO::getSkuCode, ProductSkuBaseDO::getId, (k1, k2) -> k2));
        Map<String, ProductExcelRowDTO> supplier = list.stream()
                .filter(x->Objects.nonNull(x.getSupplierId()))
                .collect(Collectors.toMap(k -> k.getStyleNumber() + k.getSkuCode() + k.getSupplierId(), v -> v, (k1, k2) -> k2));
        // 供应商
        for (ProductExcelRowDTO value : supplier.values()) {
            if (Objects.isNull(value.getSupplierId())) {
                continue;
            }
            ProductSkuSupplierBaseDO supplierBase = new ProductSkuSupplierBaseDO();
            supplierBaseList.add(supplierBase);
            supplierBase.setId(IdGenUtil.getId());
            supplierBase.setProductId(productBaseDO.getId());
            supplierBase.setProductSkuId(skuIdMap.get(value.getSkuCode()));
            supplierBase.setSupplierId(value.getSupplierId());
            supplierBase.setCreateTime(now);
            supplierBase.setUpdateTime(now);
            supplierBase.setCreateUserId(rowFieldRecord.getUserId());
            supplierBase.setUpdateUserId(rowFieldRecord.getUserId());

            KingHoodExceptionUtil.isNull(supplierBase.getProductSkuId(),"供应商需要匹配sku");

            for (int i = rowFieldRecord.getSupplierStart(); i <= rowFieldRecord.getSupplierEnd(); i++) {
                ExcelDataInfoDTO info = value.getMap().get(i);
                // 下标不一定有值，excel在前面没有填的是null值，但是最后的列是完全没有值
                if (Objects.isNull(info) || Objects.isNull(info.getAttributeId()) || StringUtils.isEmpty(info.getValue())) {
                    continue;
                }
                ProductAttributeDO attribute = new ProductAttributeDO();
                attributes.add(attribute);
                attribute.setId(IdGenUtil.getId());
                attribute.setProductId(productBaseDO.getId());
                attribute.setBusinessId(supplierBase.getId());
                attribute.setBusinessType(ProductAttributeDO.BUSINESS_TYPE_SUPPLIER);
                attribute.setAttributeId(info.getAttributeId());
                attribute.setAttributeCode(info.getAttributeCode());
                attribute.setValueType(info.getValueType());
                attribute.setValue(ProductBaseHandler.handleAttributeValue(info));
//                attribute.setValueFind(ProductBaseHandler.handleAttributeValueFind(info));
                attribute.setValueFind(attribute.getValue());
                attribute.setCreateTime(now);
                attribute.setUpdateTime(now);
                attribute.setCreateUserId(rowFieldRecord.getUserId());
                attribute.setUpdateUserId(rowFieldRecord.getUserId());
            }
        }

        Map<String, ProductExcelRowDTO> extrasMap = list.stream()
                .filter(x->Objects.nonNull(x.getExtras()))
                .collect(Collectors.toMap(k -> k.getStyleNumber() + k.getSkuCode() + k.getExtras(), v -> v, (k1, k2) -> k2));
        // sku附件
        for (ProductExcelRowDTO value : extrasMap.values()) {
            if (StringUtils.isEmpty(value.getExtras())) {
                continue;
            }
            ProductSkuExtrasBaseDO extrasBase = new ProductSkuExtrasBaseDO();
            extrasBaseList.add(extrasBase);
            extrasBase.setId(IdGenUtil.getId());
            extrasBase.setProductId(productBaseDO.getId());
            extrasBase.setProductSkuId(skuIdMap.get(value.getSkuCode()));
            extrasBase.setCreateTime(now);
            extrasBase.setUpdateTime(now);
            extrasBase.setCreateUserId(rowFieldRecord.getUserId());
            extrasBase.setUpdateUserId(rowFieldRecord.getUserId());

            KingHoodExceptionUtil.isNull(extrasBase.getProductSkuId(),"附件需要匹配sku");

            for (int i = rowFieldRecord.getExtrasStart(); i <= rowFieldRecord.getExtrasEnd(); i++) {
                ExcelDataInfoDTO info = value.getMap().get(i);
                if (Objects.isNull(info.getAttributeId()) || StringUtils.isEmpty(info.getValue())) {
                    continue;
                }
                ProductAttributeDO attribute = new ProductAttributeDO();
                attributes.add(attribute);
                attribute.setId(IdGenUtil.getId());
                attribute.setProductId(productBaseDO.getId());
                attribute.setBusinessId(extrasBase.getId());
                attribute.setBusinessType(ProductAttributeDO.BUSINESS_TYPE_EXTRAS);
                attribute.setAttributeId(info.getAttributeId());
                attribute.setAttributeCode(info.getAttributeCode());
                attribute.setValueType(info.getValueType());
                attribute.setValue(ProductBaseHandler.handleAttributeValue(info));
//                attribute.setValueFind(ProductBaseHandler.handleAttributeValueFind(info));
                attribute.setValueFind(attribute.getValue());
                attribute.setCreateTime(now);
                attribute.setUpdateTime(now);
                attribute.setCreateUserId(rowFieldRecord.getUserId());
                attribute.setUpdateUserId(rowFieldRecord.getUserId());
            }
        }

        return res;
    }

    /**
     * 检查数据重复
     */
    public static boolean checkSameData(List<ProductExcelRowDTO> list, RowFieldRecordDTO rowFieldRecord, BaseProductDaoDTO dao) {

        boolean bad = checkSameImportant(list, rowFieldRecord, dao);
        if (bad) {
            return bad;
        }
        bad = checkSameDataRange(list, null, null, rowFieldRecord.getProductStart(), rowFieldRecord.getProductEnd(), "相同款式的数据必须保持一致",rowFieldRecord.getSize());
        if (bad) {
            return bad;
        }
        bad = checkSameDataRange(list, rowFieldRecord.getProductStart(), null, rowFieldRecord.getSkuStart(), rowFieldRecord.getSkuEnd(), "相同sku的数据必须保持一致",rowFieldRecord.getSize());
        if (bad) {
            return bad;
        }
        bad = checkSameDataRange(list, rowFieldRecord.getProductStart(), rowFieldRecord.getSkuStart(), rowFieldRecord.getSupplierStart(), rowFieldRecord.getSupplierEnd(), "相同sku供应商的数据必须保持一致",rowFieldRecord.getSize());
        if (bad) {
            return bad;
        }
        bad = checkSameDataRange(list, rowFieldRecord.getProductStart(), rowFieldRecord.getSkuStart(), rowFieldRecord.getExtrasStart(), rowFieldRecord.getExtrasEnd(), "相同sku附件的数据必须保持一致",rowFieldRecord.getSize());
        return bad;
    }

    /**
     * 检查关键字段
     */
    private static boolean checkSameImportant(List<ProductExcelRowDTO> list, RowFieldRecordDTO rowFieldRecord, BaseProductDaoDTO dao) {

        ArrayList<String> important = new ArrayList<>();
        list.forEach(x -> {
            StringBuilder sb = new StringBuilder();
            ExcelDataInfoDTO index = x.getMap().get(rowFieldRecord.getProductStart());
            if (Objects.isNull(index) || StringUtils.isEmpty(index.getValue())) {
                // 必填
                badData(x, "款式编码必填",rowFieldRecord.getSize());
                return;
            }
            sb.append(index.getValue()).append("-");

            if (Objects.nonNull(rowFieldRecord.getSkuStart())) {
                ExcelDataInfoDTO index1 = x.getMap().get(rowFieldRecord.getSkuStart());
                if (Objects.nonNull(index1) && !StringUtils.isEmpty(index1.getValue())) {
                    if (dao.getSkuCodeList().contains(index1.getValue())) {
                        badData(x, "sku编码已存在",rowFieldRecord.getSize());
                        return;
                    }
                    sb.append(index1.getValue()).append("-");
                }
            }

            if (Objects.nonNull(rowFieldRecord.getSupplierStart())) {
                ExcelDataInfoDTO index2 = x.getMap().get(rowFieldRecord.getSupplierStart());
                if (Objects.nonNull(index2) && !StringUtils.isEmpty(index2.getValue())) {
                    sb.append(index2.getValue()).append("-");
                }
            }

            if (Objects.nonNull(rowFieldRecord.getExtrasStart())) {
                ExcelDataInfoDTO index3 = x.getMap().get(rowFieldRecord.getExtrasStart());
                if (Objects.nonNull(index3) && !StringUtils.isEmpty(index3.getValue())) {
                    sb.append(index3.getValue()).append("-");
                    x.setExtras(index3.getValue());
                }
            }

            String one = sb.toString();
            if (important.contains(one)) {
                badData(x, "数据重复",rowFieldRecord.getSize());
            } else {
                important.add(one);
            }
        });
        boolean bad = list.stream().anyMatch(ProductExcelRowDTO::isBad);
        return bad;
    }

    /**
     * 检查数据重复
     */
    private static boolean checkSameDataRange(List<ProductExcelRowDTO> list, Integer productIndex, Integer skuIndex, Integer businessIndex, Integer end, String message,int size) {

        if (Objects.isNull(businessIndex) || Objects.isNull(end)) {
            return false;
        }
        Map<String, List<String>> dataMap = new HashMap<>();
        list.forEach(x -> {
            boolean add = false;
            // 关联数据可以不填，如果businessIndex无法获取到数据，则认为用户未填该项
            StringBuilder sb = new StringBuilder();
            if (Objects.nonNull(productIndex)) {
                ExcelDataInfoDTO index = x.getMap().get(productIndex);
                if (Objects.nonNull(index) && !StringUtils.isEmpty(index.getValue())) {
                    sb.append(index.getValue()).append("-");
                }
            }
            if (Objects.nonNull(skuIndex)) {
                ExcelDataInfoDTO index = x.getMap().get(skuIndex);
                if (Objects.nonNull(index) && !StringUtils.isEmpty(index.getValue())) {
                    sb.append(index.getValue()).append("-");
                }
            }
            ExcelDataInfoDTO index = x.getMap().get(businessIndex);
            if (Objects.isNull(index) || StringUtils.isEmpty(index.getValue())) {
                return;
            }
            sb.append(index.getValue()).append("-");
            List<String> dataList = dataMap.get(sb.toString());
            if (CollectionUtils.isEmpty(dataList)) {
                add = true;
                dataList = new ArrayList<>();
                dataMap.put(sb.toString(), dataList);
            }
            for (int i = businessIndex + 1; i <= end; i++) {
                ExcelDataInfoDTO data = x.getMap().get(i);
                if (Objects.isNull(data)) {
                    log.info("第{}列未找到数据",i);
                    continue;
                }
                if (add) {
                    dataList.add(data.getValue());
                } else if (!dataList.contains(data.getValue())) {
                    badData(x, message,size);
                }
            }
        });
        boolean bad = list.stream().anyMatch(ProductExcelRowDTO::isBad);
        return bad;
    }

    /**
     * 数据错误
     */
    public static void badData(ProductExcelRowDTO x, String message,int size) {
        x.setBad(true);
        x.setBadMessage(message);
        ExcelDataInfoDTO one = new ExcelDataInfoDTO();
        one.setIndex(size);
        one.setValue("导入失败");
        one.setBad(true);
        x.getMap().put(size, one);
        ExcelDataInfoDTO two = new ExcelDataInfoDTO();
        two.setIndex(size + 1);
        two.setValue(message);
        two.setBad(true);
        x.getMap().put(size + 1, two);
    }

    /**
     * 返回第一个list是行，第二个list是列
     */
    public static List<List<String>> head(Map<Integer, String> head) {

        List<List<String>> list = ListUtils.newArrayList();
        head.values().forEach(x -> {
            if(Objects.isNull(x)){
                return;
            }
            list.add(Collections.singletonList(x));
        });
        list.add(Collections.singletonList("导入结果"));
        list.add(Collections.singletonList("失败原因"));

        return list;
    }

    /**
     * 封装返回
     */
    public static List<List<String>> dataList(List<Map<Integer, String>> allDataList) {
        List<List<String>> list = ListUtils.newArrayList();

        for (Map<Integer, String> map : allDataList) {
            List<String> data = new ArrayList<>();
            Integer size = map.keySet().stream().max(Integer::compareTo).orElse(0);
            for (int i = 0; i < size + 1; i++) {
                String s = map.get(i);
                data.add(s);
            }
            list.add(data);
        }

        return list;
    }

    public static ProductBaseDTO getProductBase(BaseProductDTODO product, Map<String, List<ProductAttributeDO>> attributeMap) {
        ProductBaseDTO productBaseDTO = new ProductBaseDTO();
        BeanUtils.copyProperties(product, productBaseDTO);

        String key = product.getId() + "-" + ProductAttributeDO.BUSINESS_TYPE_PRODUCT;
        List<ProductAttributeDO> attributeList = attributeMap.get(key);
        if (CollectionUtils.isEmpty(attributeList)) {
            return productBaseDTO;
        }
        Map<String, String> attributes = attributeList.stream()
                .filter(Objects::nonNull)
                .filter(x -> Objects.nonNull(x.getAttributeCode()))
                .filter(x -> Objects.nonNull(x.getValue()))
                .collect(Collectors.toMap(ProductAttributeDO::getAttributeCode, ProductAttributeDO::getValue, (k1, k2) -> k2));
        productBaseDTO.setAttributes(attributes);

        return productBaseDTO;
    }

    public static List<ProductSkuDTO> getSkuList(BaseProductDTODO product, Map<String, List<ProductAttributeDO>> attributeMap) {
        if (CollectionUtils.isEmpty(product.getSkuList())) {
            return null;
        }
        List<ProductSkuDTO> list = new ArrayList<>();
        for (BaseProductSkuEtcDTO sku : product.getSkuList()) {
            ProductSkuDTO one = new ProductSkuDTO();
            list.add(one);

            one.setId(sku.getId());
            one.setSkuUuid(sku.getSkuUuid());
            one.setSkuCode(sku.getSkuCode());
            one.setSkuStatus(sku.getSkuStatus());

            String key = one.getId() + "-" + ProductAttributeDO.BUSINESS_TYPE_SKU;
            List<ProductAttributeDO> attributeList = attributeMap.get(key);
            if (CollectionUtils.isEmpty(attributeList)) {
                continue;
            }
            Map<String, String> attributes = attributeList.stream()
                    .filter(Objects::nonNull)
                    .filter(x -> Objects.nonNull(x.getAttributeCode()))
                    .filter(x -> Objects.nonNull(x.getValue()))
                    .collect(Collectors.toMap(ProductAttributeDO::getAttributeCode, ProductAttributeDO::getValue, (k1, k2) -> k2));
            one.setAttributes(attributes);
        }

        return list;
    }


    public static List<ProductSkuExtrasDTO> getSkuExtrasList(BaseProductDTODO product, Map<String, List<ProductAttributeDO>> attributeMap) {

        if (CollectionUtils.isEmpty(product.getExtrasList())) {
            return null;
        }

        List<ProductSkuExtrasDTO> list = new ArrayList<>();

        for (BaseProductSkuEtcDTO x : product.getExtrasList()) {
            ProductSkuExtrasDTO one = new ProductSkuExtrasDTO();
            list.add(one);

            one.setId(x.getId());
            one.setSkuUuid(x.getSkuUuid());
            one.setSkuCode(x.getSkuCode());
            one.setSkuStatus(x.getSkuStatus());

            String key = one.getId() + "-" + ProductAttributeDO.BUSINESS_TYPE_EXTRAS;
            List<ProductAttributeDO> attributeList = attributeMap.get(key);
            if (CollectionUtils.isEmpty(attributeList)) {
                continue;
            }
            Map<String, String> attributes = attributeList.stream()
                    .filter(Objects::nonNull)
                    .filter(z -> Objects.nonNull(z.getAttributeCode()))
                    .filter(y -> Objects.nonNull(y.getValue()))
                    .collect(Collectors.toMap(ProductAttributeDO::getAttributeCode, ProductAttributeDO::getValue, (k1, k2) -> k2));
            one.setAttributes(attributes);
        }
        return list;
    }

    public static List<ProductSupplierDTO> getSkuSupplierList(BaseProductDTODO product, Map<String, List<ProductAttributeDO>> attributeMap) {

        if (CollectionUtils.isEmpty(product.getSupplierList())) {
            return null;
        }
        List<ProductSupplierDTO> list = new ArrayList<>();
        for (BaseProductSkuEtcDTO x : product.getSupplierList()) {
            ProductSupplierDTO one = new ProductSupplierDTO();
            list.add(one);

            one.setId(x.getId());
            one.setSkuUuid(x.getSkuUuid());
            one.setSkuCode(x.getSkuCode());
            one.setSkuStatus(x.getSkuStatus());
            one.setSupplierId(x.getSupplierId());

            String key = one.getId() + "-" + ProductAttributeDO.BUSINESS_TYPE_SUPPLIER;
            List<ProductAttributeDO> attributeList = attributeMap.get(key);
            if (CollectionUtils.isEmpty(attributeList)) {
                continue;
            }
            Map<String, String> attributes = attributeList.stream()
                    .filter(Objects::nonNull)
                    .filter(z -> Objects.nonNull(z.getAttributeCode()))
                    .filter(y -> Objects.nonNull(y.getValue()))
                    .collect(Collectors.toMap(ProductAttributeDO::getAttributeCode, ProductAttributeDO::getValue, (k1, k2) -> k2));
            one.setAttributes(attributes);
        }
        return list;
    }

    public static Map<Integer, ProductExcelAttributeDTO> checkExcelHead(Map<Integer, String> dataMap, BaseProductDaoDTO dao,boolean m) {

        Collection<String> values = dataMap.values().stream().map(ProductBaseHandler::handleValueParam)
                .filter(Objects::nonNull).collect(Collectors.toList());
        HashMap<String, String> sysMap = new HashMap<>();
        sysMap.put("款号", "styleNumber");
        sysMap.put("款式名称", "styleName");
        sysMap.put("状态", "status");
        sysMap.put("品牌名称", "brand");
        sysMap.put("货类", "goods");
        sysMap.put("品类", "category");
        sysMap.put("SKU编码", "skuCode");
        sysMap.put("SKU状态", "skuStatus");
        sysMap.put("供应商", "supplier");

        if(m){
            List<String> match = Arrays.asList("款号", "款式名称", "状态");
            boolean flag = match.stream().allMatch(values::contains);
            KingHoodExceptionUtil.trueThrows(!flag, match.toString() + "都是必填的");
        }

        HashMap<Integer, ProductExcelAttributeDTO> fieldMap = new HashMap<>();
        dataMap.forEach((key, value) -> {
            // 去掉*
            value = ProductBaseHandler.handleValueParam(value);
            if(StringUtils.isEmpty(value)){
                return;
            }
            ProductExcelAttributeDTO a = new ProductExcelAttributeDTO();
            a.setValue(value);
            fieldMap.put(key, a);

            String code = sysMap.get(value);
            if (Objects.nonNull(code)) {
                a.setIsAttribute(false);
                a.setCode(code);
                return;
            }
            BaseAttributeDO baseAttributeDO = dao.getAttributeMap().get(value);
            if (Objects.isNull(baseAttributeDO)) {
                KingHoodExceptionUtil.isNull(baseAttributeDO, "属性【" + value + "】不支持");
            }
            a.setIsAttribute(true);
            a.setAttributeCode(baseAttributeDO.getAttributeCode());
            a.setAttributeName(baseAttributeDO.getAttributeName());
            a.setAttributeId(baseAttributeDO.getId());
            a.setValueType(baseAttributeDO.getValueType());
            a.setValueCode(baseAttributeDO.getValueCode());
            a.setIsMultipleChoice(baseAttributeDO.getIsMultipleChoice());
            BaseAttributeLimitDO attributeLimitDO = dao.getAttributeLimitMap().get(baseAttributeDO.getId());
            a.setAttributeLimit(attributeLimitDO);
            List<BaseAttributeValueDO> attributeValueDOList = dao.getAttributeValueMap().get(baseAttributeDO.getId());
            if (!CollectionUtils.isEmpty(attributeValueDOList)) {
                Map<String, BaseAttributeValueDO> attributeValueDOMap = attributeValueDOList.stream()
                        .collect(Collectors.toMap(BaseAttributeValueDO::getValue, v -> v, (k1, k2) -> k2));
                a.setAttributeValueMap(attributeValueDOMap);
            }
        });

        return fieldMap;
    }


    public static RowFieldRecordDTO handleHeadCode(Map<Integer, ProductExcelAttributeDTO> headCodeMap) {

        RowFieldRecordDTO record = new RowFieldRecordDTO();
        record.setProductStart(0);
        record.setSize(headCodeMap.size());
        record.setProductEnd(headCodeMap.size() - 1);
        record.setSkuEnd(headCodeMap.size() - 1);
        record.setExtrasEnd(headCodeMap.size() - 1);
        record.setSupplierEnd(headCodeMap.size() - 1);

        headCodeMap.forEach((k, v) -> {
            if (Objects.nonNull(v.getCode())) {
                switch (v.getCode()) {
                    case "styleNumber":
                        record.setProductStart(k);
                        break;
                    case "skuCode":
                        KingHoodExceptionUtil.isNull(record.getProductStart(), "sku信息需要在款号后面");
                        record.setProductEnd(k - 1);
                        record.setSkuStart(k);
                        break;
                    case "supplier":
                        KingHoodExceptionUtil.isNull(record.getSkuStart(), "供应商信息需要在sku信息后面");
                        record.setSkuEnd(k - 1);
                        record.setSupplierStart(k);
                        break;
                    default:
                }
            } else if (Objects.equals("附件", v.getValue())) {
                KingHoodExceptionUtil.isNull(record.getSupplierStart(), "附件信息需要在供应商信息后面");
                record.setSupplierEnd(k - 1);
                record.setExtrasStart(k);
            }
        });
        if (Objects.isNull(record.getSkuStart())) {
            record.setSkuEnd(null);
        }
        if (Objects.isNull(record.getExtrasStart())) {
            record.setExtrasEnd(null);
        }
        if (Objects.isNull(record.getSupplierStart())) {
            record.setSupplierEnd(null);
        }

        return record;
    }

    /**
     * 将商品的数据封装到模板
     */
    public static void handleProductTemplateData(ProductDetailVO res, ProductDTO product) {

        // 品牌，品类等基本数据copy
        BeanUtils.copyProperties(product, res);

        Optional<ProductDTO> op = Optional.ofNullable(product);
        res.setProductId(op.map(ProductDTO::getProductBase).map(ProductBaseDTO::getId).orElse(null));
        res.setStyleNumber(op.map(ProductDTO::getProductBase).map(ProductBaseDTO::getStyleNumber).orElse(null));
        res.setStyleName(op.map(ProductDTO::getProductBase).map(ProductBaseDTO::getStyleName).orElse(null));
        res.setStatus(op.map(ProductDTO::getProductBase).map(ProductBaseDTO::getStatus).orElse(null));

        for (ProductTemplateNodeDTO head : res.getNodeList()) {
            switch (head.getGroupCode()) {
                case "sku_info":
                    handleSku(head, op);
                    break;
                case "price_info":
                    handleSkuPrice(head, op);
                    break;
                case "sku_extras_info":
                    handleSkuExtras(head, op);
                    break;
                case "supplier_info":
                    handleSkuSupplier(head, op);
                    break;
                default:
                    handleBase(head, op);
            }
        }
    }

    private static void handleBase(ProductTemplateNodeDTO head, Optional<ProductDTO> op) {

        ArrayList<ProductTemplateNodeAttributeDTO> all = new ArrayList<>();
        int depth = 1;
        head.handleAttribute(all, depth);

        Map<String, String> attributeMap = op.map(ProductDTO::getProductBase)
                .map(ProductBaseDTO::getAttributes).orElse(null);
        if (Objects.isNull(attributeMap)) {
            return;
        }
        if (!CollectionUtils.isEmpty(all)) {
            all.forEach(x -> x.setValue(attributeMap.get(x.getAttributeCode())));
        }
    }

    private static void handleSkuSupplier(ProductTemplateNodeDTO head, Optional<ProductDTO> op) {

        List<ProductSupplierDTO> supplierDTOList = op.map(ProductDTO::getSkuSupplierList).orElse(null);
        if (CollectionUtils.isEmpty(supplierDTOList)) {
            return;
        }

        List<ProductTemplateNodeDataDTO> dataList = new ArrayList<>();
        head.setDataList(dataList);
        for (ProductSupplierDTO one : supplierDTOList) {
            ProductTemplateNodeDataDTO data = new ProductTemplateNodeDataDTO();
            dataList.add(data);
            data.setSkuId(one.getId());
            data.setSkuUuid(one.getSkuUuid());
            data.setSkuCode(one.getSkuCode());
            data.setSkuStatus(one.getSkuStatus());
            data.setSupplierId(one.getSupplierId());
            data.setAttributeMap(one.getAttributes());
        }

    }

    private static void handleSkuExtras(ProductTemplateNodeDTO head, Optional<ProductDTO> op) {

        List<ProductSkuExtrasDTO> skuExtrasDTOList = op.map(ProductDTO::getSkuExtrasList).orElse(null);
        if (CollectionUtils.isEmpty(skuExtrasDTOList)) {
            return;
        }

        List<ProductTemplateNodeDataDTO> dataList = new ArrayList<>();
        head.setDataList(dataList);
        for (ProductSkuExtrasDTO one : skuExtrasDTOList) {
            ProductTemplateNodeDataDTO data = new ProductTemplateNodeDataDTO();
            dataList.add(data);
            data.setSkuId(one.getId());
            data.setSkuUuid(one.getSkuUuid());
            data.setSkuCode(one.getSkuCode());
            data.setSkuStatus(one.getSkuStatus());
            data.setAttributeMap(one.getAttributes());
        }
    }

    private static void handleSkuPrice(ProductTemplateNodeDTO head, Optional<ProductDTO> op) {

        List<ProductSkuDTO> skuDTOList = op.map(ProductDTO::getSkuList).orElse(null);
        ProductBaseDTO productBaseDTO = op.map(ProductDTO::getProductBase).orElse(null);

        List<ProductTemplateNodeDTO> sunNodeList = head.getSunNodeList();
        for (ProductTemplateNodeDTO sun : sunNodeList) {
            if (Objects.equals(sun.getGroupCode(), "style_price")) {
                ArrayList<ProductTemplateNodeAttributeDTO> all = new ArrayList<>();
                int depth = 1;
                sun.handleAttribute(all, depth);
                Map<String, String> attributeMap = productBaseDTO.getAttributes();
                if (Objects.isNull(attributeMap)) {
                    continue;
                }
                if (!CollectionUtils.isEmpty(all)) {
                    all.forEach(x -> x.setValue(attributeMap.get(x.getAttributeCode())));
                }
            }
            if (Objects.equals(sun.getGroupCode(), "sku_price")) {
                if (CollectionUtils.isEmpty(skuDTOList) || CollectionUtils.isEmpty(sun.getAttributeList())) {
                    continue;
                }
                List<String> needCode = sun.getAttributeList().stream()
                        .map(ProductTemplateNodeAttributeDTO::getAttributeCode)
                        .collect(Collectors.toList());
                List<ProductTemplateNodeDataDTO> dataList = new ArrayList<>();
                sun.setDataList(dataList);
                for (ProductSkuDTO sku : skuDTOList) {
                    // 如果sku的属性没有一个可以匹配的就直接忽略了
                    if(CollectionUtils.isEmpty(sku.getAttributes())){
                        continue;
                    }
                    HashMap<String, String> attributes = new HashMap<>();
                    sku.getAttributes().forEach((k,y)->{
                        if(needCode.contains(k)){
                            attributes.put(k,y);
                        }
                    });
                    if(CollectionUtils.isEmpty(attributes)){
                        continue;
                    }
                    ProductTemplateNodeDataDTO data = new ProductTemplateNodeDataDTO();
                    data.setSkuId(sku.getId());
                    data.setSkuUuid(sku.getSkuUuid());
                    data.setSkuCode(sku.getSkuCode());
                    data.setSkuStatus(sku.getSkuStatus());
                    data.setAttributeMap(attributes);
                    dataList.add(data);
                }
            }
        }
    }

    private static void handleSku(ProductTemplateNodeDTO head, Optional<ProductDTO> op) {

        List<ProductSkuDTO> skuDTOList = op.map(ProductDTO::getSkuList).orElse(null);
        if (CollectionUtils.isEmpty(skuDTOList)) {
            return;
        }

        List<ProductTemplateNodeDataDTO> dataList = new ArrayList<>();
        head.setDataList(dataList);
        for (ProductSkuDTO sku : skuDTOList) {
            ProductTemplateNodeDataDTO data = new ProductTemplateNodeDataDTO();
            dataList.add(data);
            data.setSkuId(sku.getId());
            data.setSkuUuid(sku.getSkuUuid());
            data.setSkuCode(sku.getSkuCode());
            data.setSkuStatus(sku.getSkuStatus());
            data.setAttributeMap(sku.getAttributes());
        }
    }

    public static String getSizeName(long size) {

        KingHoodExceptionUtil.trueThrows(size > LIMIT_SIZE, "不支持大文件导入");

        // G
        if (size > UNIT_SIZE * UNIT_SIZE * UNIT_SIZE) {
            size = size / UNIT_SIZE * UNIT_SIZE;
            long s = size / UNIT_SIZE;
            long m = (size % UNIT_SIZE) / 102;
            if (m > 0) {
                return s + "." + m + "G";
            } else {
                return s + "G";
            }
        }
        // M
        if (size > UNIT_SIZE * UNIT_SIZE) {
            size = size / UNIT_SIZE;
            long s = size / UNIT_SIZE;
            long m = (size % UNIT_SIZE) / 102;
            if (m > 0) {
                return s + "." + m + "M";
            } else {
                return s + "M";
            }
        }
        // KB
        if (size > UNIT_SIZE) {
            long s = size / UNIT_SIZE;
            long m = (size % UNIT_SIZE) / 102;
            if (m > 0) {
                return s + "." + m + "KB";
            } else {
                return s + "KB";
            }
        }
        // B
        return size + "B";
    }

    public static boolean returnValue(String value,String valueCode){
        if (StringUtils.isEmpty(value)) {
            return true;
        }
        List<AttributeValueCodeEnum> list = Arrays.asList(AttributeValueCodeEnum.SELECT, AttributeValueCodeEnum.LEVEL_SELECT,
                AttributeValueCodeEnum.RADIO, AttributeValueCodeEnum.CHECK_BOX, AttributeValueCodeEnum.DATE);
        List<String> codeList = list.stream().map(AttributeValueCodeEnum::getCode).collect(Collectors.toList());
        if (!codeList.contains(valueCode)) {
            return true;
        }
        return false;
    }


    /**
     * 将value处理成id
     * AttributeTypeEnum
     */
    public static String handleAttributeValue(ExcelDataInfoDTO info) {

        String valueCode = info.getValueCode();
        String value = info.getValue();
        boolean r = returnValue(info.getValue(),info.getValueCode());
        if(r){
            return value;
        }

        if (Objects.equals(valueCode, AttributeValueCodeEnum.DATE.getCode())) {
            return handleTime(value);
        }
        // 匹配得到数据
        List<Long> idList = getAttributeId(info, value);
        List<String> codeList = Arrays.asList(AttributeValueCodeEnum.RADIO.getCode(), AttributeValueCodeEnum.CHECK_BOX.getCode(),
                AttributeValueCodeEnum.SELECT.getCode(), AttributeValueCodeEnum.LEVEL_SELECT.getCode());
        if (codeList.contains(valueCode)) {
            return  idList.stream()
                    .map(String::valueOf)
                    .collect(Collectors.joining(","));
        }

//        if (Objects.equals(valueCode, AttributeValueCodeEnum.SELECT.getCode())) {
//            if (Objects.equals(info.getIsMultipleChoice(), 1)) {
//                return JSON.toJSONString(Collections.singletonList(id));
//            }
//            return id.toString();
//        }
//        if (Objects.equals(valueCode, AttributeValueCodeEnum.LEVEL_SELECT.getCode())) {
//            List<Long> levelId = getAttributeLevelId(info.getAttributeValueMap(), value);
//            if (Objects.equals(info.getIsMultipleChoice(), 1)) {
//                ArrayList<List<Long>> objects = new ArrayList<>(1);
//                objects.add(levelId);
//                return JSON.toJSONString(objects);
//            }
//            return JSON.toJSONString(levelId);
//        }

        return value;
    }

    private static String handleTime(String value) {
        Date rightDate = null;
        if (TIME_PATTERN.matcher(value).matches()) {
            return value;
        } else if (TIME_PATTERN01.matcher(value).matches()) {
            return value;
        } else if (TIME_PATTERN2.matcher(value).matches()) {
            try {
                rightDate = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse(value);
            } catch (Exception e) {
                KingHoodExceptionUtil.throwException("解析时间出错，正确格式yyyy/MM/dd HH:mm:ss");
            }
        } else if (TIME_PATTERN21.matcher(value).matches()) {
            try {
                rightDate = new SimpleDateFormat("yyyy/MM/dd").parse(value);
            } catch (Exception e) {
                KingHoodExceptionUtil.throwException("解析时间出错，正确格式yyyy/MM/dd");
            }
        } else {
            try {
                SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", java.util.Locale.US);
                rightDate = sdf.parse(value);
            } catch (Exception e) {
                KingHoodExceptionUtil.throwException("时间格式错误，正确格式yyyy/MM/dd hh:mm:ss或者yyyy-MM-dd HH:mm:ss");
            }
        }

        return DateFormatUtils.format(rightDate, "yyyy-MM-dd HH:mm:ss");
    }

    /***
     * 多级属性
     * */
    private static List<Long> getAttributeLevelId(Map<String, BaseAttributeValueDO> attributeValueMap, String value) {

        BaseAttributeValueDO valueDO = attributeValueMap.get(value);
        KingHoodExceptionUtil.isNull(valueDO, "属性值" + valueDO + "不存在");
        String idPath = valueDO.getIdPath();
        String[] split = idPath.split("/");
        ArrayList<Long> res = new ArrayList<>();
        for (String path : split) {
            res.add(Long.valueOf(path));
        }

        return res;
    }

    /***
     * 单个属性
     * */
    private static List<Long> getAttributeId(ExcelDataInfoDTO info, String value) {

        Map<String, BaseAttributeValueDO> attributeValueMap = info.getAttributeValueMap();
        String[] split = value.split(",");
        if(!Objects.equals(info.getIsMultipleChoice(),1) && split.length > 1){
            KingHoodExceptionUtil.throwException(info.getAttributeName() + "不支持多选");
        }
        ArrayList<Long> res = new ArrayList<>();
        for (String s : split) {
            BaseAttributeValueDO valueDO = attributeValueMap.get(s);
            KingHoodExceptionUtil.isNull(valueDO, "属性值" + value + "不存在");
            res.add(valueDO.getId());
        }

        return res;
    }

    /**
     * 处理属性的value
     */
    public static String handleAttributeValue(Object in) {

        if(Objects.isNull(in)){
            return null;
        }

        if (in instanceof String) {
            return (String) in;
        }
        return JSON.toJSONString(in);
    }

    /**
     * 处理属性的value
     */
    public static String handleAttributeValueFind(String in) {
        if(StringUtils.isEmpty(in)){
            return in;
        }
        if(in.contains("[")){
           in = in.replaceAll("\\[","");
        }
        if(in.contains("]")){
            in = in.replaceAll("]","");
        }
        return in;
    }

    /**
     * 封装sku的计价
     */
    public static void handleSaveProduct(List<ProductSkuReqDTO> skuList,List<ProductSkuReqDTO> skuPriceList) {

        if (CollectionUtils.isEmpty(skuPriceList)) {
            return;
        }
        Map<String, ProductSkuReqDTO> skuMap = skuList.stream()
                .collect(Collectors.toMap(ProductSkuReqDTO::getSkuCode, v -> v, (k1, k2) -> k2));

        for (ProductSkuReqDTO skuPrice : skuPriceList) {
            ProductSkuReqDTO sku = skuMap.get(skuPrice.getSkuCode());
            KingHoodExceptionUtil.isNull(sku, "sku的计价信息的sku code不存在");
            if (CollectionUtils.isEmpty(skuPrice.getAttributes()) || CollectionUtils.isEmpty(sku.getAttributes())) {
                continue;
            }
            sku.getAttributes().putAll(skuPrice.getAttributes());
        }
    }

    /**
     * 获取sku的模板
     * */
    public static void getSkuTemplate(ProductDetailVO res) {
        if(CollectionUtils.isEmpty(res.getNodeList())){
            return ;
        }
        List<ProductTemplateNodeDTO> skuTemplate = res.getNodeList().stream()
                .filter(x -> !Objects.equals("base_info", x.getGroupCode())
                        && !Objects.equals("operate_info", x.getGroupCode()))
                .collect(Collectors.toList());
        res.setNodeList(skuTemplate);
    }

    /**
     * 将sku的数据转成商品的
     * */
    public static BaseProductDTODO changeToProductInfo(List<SkuDTO> skuInfoList) {

        BaseProductDTODO res = new BaseProductDTODO();
        List<BaseProductSkuEtcDTO> skuList = skuInfoList.stream()
                .map(x -> new BaseProductSkuEtcDTO(x.getProductId(),x.getId(), x.getSkuUuid(), x.getSkuCode(), x.getSkuStatus(), null))
                .collect(Collectors.toList());
        res.setSkuList(skuList);

        List<BaseProductSkuEtcDTO> extrasDTOS = new ArrayList<>();
        skuInfoList.forEach(x->{
            if(CollectionUtils.isEmpty(x.getExtrasList())){
                return;
            }
            extrasDTOS.addAll(x.getExtrasList());
        });
        res.setExtrasList(extrasDTOS);

        List<BaseProductSkuEtcDTO> supplierList = new ArrayList<>();
        skuInfoList.forEach(x->{
            if(CollectionUtils.isEmpty(x.getSupplierList())){
                return;
            }
            supplierList.addAll(x.getSupplierList());
        });
        res.setSupplierList(supplierList);

        return res;
    }
}
